/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Galaxium.Core;
using Galaxium.Gui;

using Anculus.Core;

namespace Galaxium.Protocol.Irc
{
	public sealed class IrcAccount : AbstractAccount
	{
		private IrcConnectionInfo _connectionInfo;
		
		private List<IrcStoredChannel> _channels;
		private List<IrcStoredContact> _contacts;
		private UserModeFlags userMode;
		private ChannelModeFlags channelUserMode;
		private bool _showConsole = false;
		
		public bool ShowConsole
		{
			get { return _showConsole; }
			set { _showConsole = value; }
		}
		
		public UserModeFlags UserMode
		{
			get { return userMode; }
			set { userMode = value; }
		}
		
		public ChannelModeFlags ChannelUserMode
		{
			get { return channelUserMode; }
			set { channelUserMode = value; }
		}
		
		public bool HasUserModes (UserModeFlags flags)
		{
			return (userMode & flags) == flags;
		}
		
		public bool HasChannelUserModes (ChannelModeFlags flags)
		{
			return (channelUserMode & flags) == flags;
		}
		
		public new IrcSession Session
		{
			get { return base.Session as IrcSession; }
		}
		
		public override string DisplayMessage
		{
			get { return base.DisplayMessage; }
			set
			{
				if (value == base.DisplayMessage)
					return;
				
				base.DisplayMessage = value;
				
				if ((Session != null) && (Session.Connection != null))
					Session.SetAwayPresence (Presence);
			}
		}
		
		public override string DisplayName
		{
			get { return base.DisplayName; }
			set
			{
				if (value == base.DisplayName)
					return;
				
				base.DisplayName = value;
				
				
				if ((Session != null) && (Session.Connection != null))
					Session.ChangeNickname (value);
			}
		}
		
		public override IPresence Presence
		{
			get { return base.Presence; }
			set
			{
				if (value == base.Presence)
					return;
				
				base.Presence = value;
				
				if ((Session != null) && (Session.Connection != null))
					Session.SetAwayPresence (Presence);
			}
		}
		
		public IrcAccount (string uid)
			: base (null, uid)
		{
			Init ();
		}

		public IrcAccount (string uid, IrcConnectionInfo connectionInfo, string password, string displayName, bool autoConnect, bool rememberPassword)
			: base (null, uid, password, displayName, autoConnect, rememberPassword)
		{
			if (connectionInfo == null)
				throw new ArgumentNullException ("connectionInfo");
			
			Init ();
			_connectionInfo = connectionInfo;
		}
		
		internal void SetDisplayName (string name)
		{
			base.DisplayName = name;
		}
		
		internal void SetPresence (IPresence presence)
		{
			base.Presence = presence;
		}
		
		internal void SetDisplayMessage (string message)
		{
			base.DisplayMessage = message;
		}
		
		private void Init ()
		{
			_channels = new List<IrcStoredChannel> ();
			_contacts = new List<IrcStoredContact> ();
			
			_presence = IrcPresence.Online;
		}
		
		public IrcConnectionInfo ConnectionInfo
		{
			get { return _connectionInfo; }
			set {
				ThrowUtility.ThrowIfNull ("ConnectionInfo", value);
				_connectionInfo = value;
			}
		}
		
		public override IProtocol Protocol
		{
			get { return IrcProtocol.Instance; }
		}
		
		public IList<IrcStoredContact> Contacts
		{
			get { return _contacts; }
		}
		
		public IList<IrcStoredChannel> Channels
		{
			get { return _channels; }
		}
		
		public void AddContacts (IEnumerable<IrcStoredContact> contacts)
		{
			if (contacts == null)
				return;
			
			_contacts.AddRange (contacts);
		}
		
		public void AddChannels (IEnumerable<IrcStoredChannel> channels)
		{
			if (channels == null)
				return;
			
			_channels.AddRange (channels);
		}
		
		public void RemoveContact (IrcContact contact)
		{
			if (contact == null)
				return;
			
			int index = -1;
			for (int i=0; i<_contacts.Count; i++) {
				if (_contacts[i].Name == contact.DisplayName) {
					index = i;
					break;
				}
			}
			
			if (index >= 0)
				_contacts.RemoveAt (index);
		}
		
		public void RemoveChannel (IrcChannel channel)
		{
			if (channel == null)
				return;
			
			int index = -1;
			for (int i=0; i<_channels.Count; i++) {
				if (_channels[i].Name == channel.DisplayName) {
					index = i;
					break;
				}
			}
			
			if (index >= 0)
				_channels.RemoveAt (index);
		}
	}
}